<template>
  <div class="roles">
    <!-- 面包屑组件 -->
    <el-breadcrumb separator="/">
      <!-- to: 路由跳转对象，同 vue-router 的 to -->
      <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>权限管理</el-breadcrumb-item>
      <el-breadcrumb-item>角色列表</el-breadcrumb-item>
    </el-breadcrumb>

    <!-- 按钮组件  : 添加角色按钮绑定事件，显示对话框 -->
    <el-button type="primary" plain @click="handleAddRole">添加角色</el-button>

     <!-- Table表格组件 : 按需求更改表格字段名  -->
     <!--
       data : 显示的数据，array
       prop : 对应列内容的字段名
      -->
      <el-table
    v-loading="loading"
    :data="roleList"
    border
    style="width: 100%"
    class="mt-15">
    <!-- 在Table表格组件中,可设置展开行  -->
    <el-table-column type="expand">
      <template slot-scope="scope">
      <!-- Layout布局组件 -->
      <!-- 第一层循环 -->
      <el-row v-for="firstItem in scope.row.children" :key="firstItem.id" >
        <el-col :span="4">
          <el-tag  closable @close="closeFirstTag(scope.row,firstItem)">{{firstItem.authName}}</el-tag>
          <i class="el-icon-arrow-right" v-if="firstItem.children.length>0"></i>
        </el-col>
        <el-col :span="20">
          <!-- 第二层循环 -->
          <el-row v-for="secondItem in firstItem.children" :key="secondItem.id">
            <el-col :span="4">
                <el-tag type="success" closable @close="closeSecondTag(scope.row,secondItem)">{{secondItem.authName}}</el-tag>
                <i class="el-icon-arrow-right" v-if="secondItem.children.length>0"></i>
            </el-col>
            <el-col :span="20">
              <!-- 第三层循环 -->
                <el-tag type="warning" closable v-for="thirdItem in secondItem.children" :key="thirdItem.id" @close="closeThirdTag(scope.row,thirdItem)">{{thirdItem.authName}}</el-tag>
            </el-col>
          </el-row>
        </el-col>
      </el-row>
       <!-- 展开行若无数据，显示提示信息 通过v-if控制显示-->
      <el-row>
        <el-col :span="24" v-if="scope.row.children.length <= 0">当前角色未设置任何权限,请前往设置</el-col>
      </el-row>
     </template>
    </el-table-column>
    <!-- 下面是未展开行的表格数据 -->
    <el-table-column
      type="index"
      width="50">
    </el-table-column>
    <el-table-column
      prop="roleName"
      label="角色名称">
    </el-table-column>
    <el-table-column
      prop="roleDesc"
      label="描述">
    </el-table-column>
    <el-table-column
        prop="address"
        label="操作">
        <!-- 表格直接渲染数据不需要使用作用域插槽，如果在表格里面需要放标签或者其他组件的时候，就需要使用作用域插槽 -->
         <template slot-scope="scope">
           <el-button type="primary" icon="el-icon-edit" plain  @click="editRole(scope.row)"></el-button>
           <!-- 通过scope对象的row属性，可以拿到点击的那一行的表格数据对象 -->
           <el-button type="danger"  icon="el-icon-delete" plain @click="handleDeleteRole(scope.row)"></el-button>
           <el-button type="warning" icon="el-icon-check" plain @click="handleGrantRole(scope.row)"></el-button>
         </template>
      </el-table-column>
   </el-table>

  <!-- 添加角色对话框 -->
    <!--
     before-close  关闭前的回调，会暂停 Dialog 的关闭
           仅当用户通过点击关闭图标或遮罩关闭 Dialog 时起效
    -->
    <el-dialog title="添加角色" :visible.sync="addDialogFormVisible" :before-close="handleClose">
      <!-- 3.5 给表单添加ref，主要用来js校验 -->
      <el-form :model="addForm" :rules="myrules" ref="addRef">
        <el-form-item label="角色名称" :label-width="formLabelWidth" prop="rolename">
          <el-input v-model="addForm.rolename" auto-complete="off"></el-input>
        </el-form-item>
        <el-form-item label="角色描述" :label-width="formLabelWidth" prop="roledes">
          <el-input v-model="addForm.roledes" auto-complete="off"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button  @click="cancelAdd">取 消</el-button>
        <el-button type="primary" @click="confirmAdd">确 定</el-button>
      </div>
    </el-dialog>

  <!-- 编辑角色对话框 -->
   <!--
     before-close  关闭前的回调，会暂停 Dialog 的关闭
           仅当用户通过点击关闭图标或遮罩关闭 Dialog 时起效
   -->
   <el-dialog title="编辑角色" :visible.sync="editDialogFormVisible" :before-close="closeEdit">
      <!-- 3.5 给表单添加ref，主要用来js校验 -->
      <el-form :model="editForm" :rules="myrules" ref="editRef">
        <el-form-item label="角色名称" :label-width="formLabelWidth" prop="rolename">
          <el-input v-model="editForm.rolename" auto-complete="off"></el-input>
        </el-form-item>
        <el-form-item label="角色描述" :label-width="formLabelWidth" prop="roledes">
          <el-input v-model="editForm.roledes" auto-complete="off"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button  @click="cancelEdit">取 消</el-button>
        <el-button type="primary" @click="confirmEdit">确 定</el-button>
      </div>
    </el-dialog>

  <!-- 授权角色对话框 -->
   <el-dialog title="授权角色" :visible.sync="grantDialogFormVisible" :before-close="closeGrant">
     <!-- 使用Tree树形控件 注意：为了能固定会话框的高度，需在控件外用大盒子包含，并设高度 -->
     <div class="tree-box">
       <!--
         data: 树形展示数据
         node-key：每个树节点的唯一标识符属性
         default-expand-all: 展开所有树节点
         default-checked-keys：默认勾选的节点的 key 的数组
         props：配置选项
        -->
       <el-tree
        :data="rightList"
        ref="tree"
        show-checkbox
        node-key="id"
        default-expand-all
        :default-checked-keys="defaultSelect"
        :props="defaultProps">
       </el-tree>
     </div>

      <div slot="footer" class="dialog-footer">
        <el-button  @click="cancelGrant">取 消</el-button>
        <el-button type="primary" @click="confirmGrant">确 定</el-button>
      </div>
    </el-dialog>

  </div>
</template>

<script>
// 引入获取角色相关的数据封装请求函数
import { getRoles, addRole, editRoles, deleteRole, getRights, deleteRolePower, addRolePower } from '@/api/handleUrl'

export default {
  data () {
    return {
      // 开启加载效果
      loading: true,
      // 存储角色列表数据
      roleList: [],
      /** * 添加角色 * **/
      // 添加角色对话框的状态  false表示隐藏
      addDialogFormVisible: false,
      // 添加角色表单
      addForm: {
        // 角色名称
        rolename: '',
        // 角色描述
        roledes: ''
      },
      /** * 编辑角色 * **/
      // 编辑角色对话框的状态  false表示隐藏
      editDialogFormVisible: false,
      // 编辑角色表单
      editForm: {
        // 角色ID
        id: '',
        // 角色名称
        rolename: '',
        // 角色描述
        roledes: ''
      },
      /** * 授权角色 * **/
      // 授权角色对话框的状态  false表示隐藏
      grantDialogFormVisible: false,
      // 树形结构数据设置
      rightList: [],
      // props属性的配置选项
      defaultProps: {
        // 指定子树为节点对象的某个属性值
        children: 'children',
        // 指定节点标签为节点对象的某个属性值
        label: 'authName'
      },
      // 当前勾选的节点数组
      defaultSelect: [],
      // 表单验证规则
      myrules: {
        rolename: [
          { required: true, message: '请输入角色名称', trigger: 'blur' }
        ],
        roledes: [
          { required: true, message: '请输入角色描述', trigger: 'blur' }
        ]
      },
      // 弹出会话框label属性的文字宽度
      formLabelWidth: '120px'
    }
  },
  created () {
    // 初始化角色列表
    this.initTable()
    // 列表数据加载完毕，关闭加载效果
    this.loading = false
  },
  methods: {
    /* 初始化角色列表 */
    initTable () {
      getRoles().then(res => {
        // console.log(res)
        if (res.meta.status === 200) {
          this.roleList = res.data
        } else {
          this.$message.error(res.meta.msg)
        }
      })
    },
    /** 删除角色指定权限  **/
    // 删除一级权限
    closeFirstTag (row, firstItem) {
      // 角色ID
      this.editForm.id = row.id
      // 权限ID
      let rightId = firstItem.id
      // 发送删除请求
      deleteRolePower(this.editForm.id, rightId)
        .then(res => {
          if (res.meta.status === 200) {
            // 更新数据
            row.children = res.data
            // 成功提示
            this.$message.success(res.meta.msg)
          } else {
            // 更新失败提示
            this.$message.error(res.meta.msg)
          }
        })
    },
    // 删除二级权限
    closeSecondTag (row, secondItem) {
      // 角色ID
      this.editForm.id = row.id
      // 权限ID
      let rightId = secondItem.id
      // 发送删除请求
      deleteRolePower(this.editForm.id, rightId)
        .then(res => {
          if (res.meta.status === 200) {
            // 更新数据
            row.children = res.data
            // 成功提示
            this.$message.success(res.meta.msg)
          } else {
            // 更新失败提示
            this.$message.error(res.meta.msg)
          }
        })
    },
    // 删除三级权限
    closeThirdTag (row, thirdItem) {
      // 角色ID
      this.editForm.id = row.id
      // 权限ID
      let rightId = thirdItem.id
      // 发送删除请求
      deleteRolePower(this.editForm.id, rightId)
        .then(res => {
          if (res.meta.status === 200) {
            // 更新数据
            row.children = res.data
            // 成功提示
            this.$message.success(res.meta.msg)
          } else {
            // 更新失败提示
            this.$message.error(res.meta.msg)
          }
        })
    },
    /** 打开添加角色会话框 **/
    handleAddRole () {
      // 显示添加对话框
      this.addDialogFormVisible = true
    },
    /* 点击 x 关闭添加角色会话框 */
    handleClose () {
      // 清除表单单项的校验结果
      this.$refs.addRef.clearValidate()
      // 重置表单
      this.addForm = {}
      // 隐藏添加对话框
      this.addDialogFormVisible = false
    },
    /* 取消添加 */
    cancelAdd () {
      // 清除表单单项的校验结果
      this.$refs.addRef.clearValidate()
      // 重置表单
      this.addForm = {}
      // 隐藏添加对话框
      this.addDialogFormVisible = false
    },
    /* 确认添加 */
    confirmAdd () {
      // js验证表单数据是否规范
      this.$refs.addRef.validate(IsPass => {
        // 验证通过
        if (IsPass) {
          addRole(this.addForm.rolename, this.addForm.roledes).then(res => {
            if (res.meta.status === 201) {
              // 隐藏对话框
              this.addDialogFormVisible = false
              // 创建成功提示
              this.$message.success(res.meta.msg)
              // 重新加载列表数据
              this.initTable()
            } else {
              // 提示创建失败信息
              this.$message.error(res.meta.msg)
            }
          })
        } else {
          // 验证不通过
          this.$message.error('请正确填写表单信息')
        }
      })
    },
    /** 编辑角色 **/
    editRole (row) {
      // 显示编辑对话框
      this.editDialogFormVisible = true
      // 分别显示当前选中的角色名称、角色描述
      this.editForm.rolename = row.roleName
      this.editForm.roledes = row.roleDesc
      // 存储当前角色ID
      this.editForm.id = row.id
    },
    /* 取消编辑 */
    cancelEdit () {
      // 移除表单校验结果
      this.$refs.editRef.clearValidate()
      // 隐藏会话框
      this.editDialogFormVisible = false
    },
    /* 确认编辑 */
    confirmEdit () {
      // console.log(this.editForm.id)
      // js验证表单数据是否规范
      this.$refs.editRef.validate(IsPass => {
        // 验证通过
        if (IsPass) {
          editRoles(this.editForm.id, { roleName: this.editForm.rolename, roleDesc: this.editForm.roledes })
            .then(res => {
              if (res.meta.status === 200) {
                // 隐藏会话框
                this.editDialogFormVisible = false
                // 重新刷新列表数据
                this.initTable()
                // 编辑成功提示
                this.$message.success('编辑成功')
              } else {
                // 编辑失败提示
                this.$message.error(res.meta.msg)
              }
            })
        } else {
          // 验证不通过
          this.$message.error('请正确填写表单信息')
        }
      })
    },
    /* 关闭编辑 */
    closeEdit () {
      // 移除表单校验结果
      this.$refs.editRef.clearValidate()
      // 隐藏会话框
      this.editDialogFormVisible = false
    },
    /** 删除某角色类 **/
    handleDeleteRole (row) {
      this.$confirm('确定要删除角色吗?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        deleteRole(row.id).then(res => {
          if (res.meta.status === 200) {
          // 重新刷新列表
            this.initTable()
            // 成功删除提示
            this.$message.success(res.meta.msg)
          } else {
          // 删除失败提示
            this.$message.success(res.meta.msg)
          }
        })
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消删除'
        })
      })
    },
    /** 授权角色 **/
    handleGrantRole (row) {
      // 角色Id  -- 为确认授权发请求准备
      this.editForm.id = row.id
      // 处理获取当前勾选节点的数组
      row.children.forEach(fitem => {
        fitem.children.forEach(sitem => {
          sitem.children.forEach(titem => {
            this.defaultSelect.push(titem.id)
          })
        })
      })
      // 显示授权会话框
      this.grantDialogFormVisible = true
      // 发送请求：获取树形展示数据
      getRights('tree').then(res => {
        // console.log(res)
        if (res.meta.status === 200) {
          this.rightList = res.data
        } else {
          this.$message.error(res.meta.msg)
        }
      })
    },
    /* 取消授权 */
    cancelGrant () {
      // 重置当前已勾选的节点数组 --  防止影响下次打开对话框的显示
      this.defaultSelect = []
      // 隐藏授权会话框
      this.grantDialogFormVisible = false
    },
    /* 关闭授权 */
    closeGrant () {
      // 重置当前已勾选的节点数组 --  防止影响下次打开对话框的显示
      this.defaultSelect = []
      // 隐藏授权会话框
      this.grantDialogFormVisible = false
    },
    /* 确认授权 */
    confirmGrant () {
      // 处理获取已选中的子节点 --  并转化为以','分割的字符串
      // 获取全选中图标的节点
      let ridsArr1 = this.$refs.tree.getCheckedKeys()
      // 获取半选中图标的节点
      let ridsArr2 = this.$refs.tree.getHalfCheckedKeys()
      // 获取全部节点
      let ridsArr = [...ridsArr1, ...ridsArr2]
      // 转化为字符串
      let ridsStr = ridsArr.join(',')
      // 发送请求
      addRolePower(this.editForm.id, ridsStr)
        .then(res => {
          if (res.meta.status === 200) {
            // 隐藏会话框
            this.grantDialogFormVisible = false
            // 刷新数据
            this.initTable()
            // 成功提示
            this.$message.success(res.meta.msg)
          } else {
            // 失败提示
            this.$message.error(res.meta.msg)
            // 隐藏会话框
            this.grantDialogFormVisible = false
          }
        })
    }
  }
}
</script>

<style lang="scss" scoped>
// 展开行样式
.el-tag {
  margin: 5px;
}
// 树形盒子
.tree-box {
  height: 300px;
  // 设置超出出现滚动条
  overflow: auto;
}
</style>
